package com.xnyzc.lhy.order.service.impl.order;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xnyzc.lhy.common.component.convert.DateToStringConverter;
import com.xnyzc.lhy.common.exception.PangException;
import com.xnyzc.lhy.common.penum.EErrorCode;
import com.xnyzc.lhy.common.penum.carpool.EInvitationPayType;
import com.xnyzc.lhy.common.penum.carpool.EInvitationPeopleType;
import com.xnyzc.lhy.common.penum.carpool.EInvitationType;
import com.xnyzc.lhy.common.penum.order.EGetCostDetailsName;
import com.xnyzc.lhy.common.penum.order.EOrderNoType;
import com.xnyzc.lhy.common.penum.order.EOrderOtherPrice;
import com.xnyzc.lhy.common.penum.wallet.EIsTransaction;
import com.xnyzc.lhy.common.penum.wallet.ERecordType;
import com.xnyzc.lhy.common.util.CheckUtil;
import com.xnyzc.lhy.common.util.ResultListUtil;
import com.xnyzc.lhy.order.entity.order.OaCOrder;
import com.xnyzc.lhy.order.entity.order.OaCOrderApprovalOfficial;
import com.xnyzc.lhy.order.entity.order.OaCOrderDeptOfficial;
import com.xnyzc.lhy.order.entity.order.OaCOrderPersonal;
import com.xnyzc.lhy.order.entity.order.OaCOrderPersonalOfficial;
import com.xnyzc.lhy.order.entity.order.OaCSelfStroke;
import com.xnyzc.lhy.order.entity.order.OaOrderOtherPrice;
import com.xnyzc.lhy.order.entity.user.wallet.OaCWalletRecord;
import com.xnyzc.lhy.order.mapper.order.OaCOrderApprovalOfficialMapper;
import com.xnyzc.lhy.order.mapper.order.OaCOrderDeptOfficialMapper;
import com.xnyzc.lhy.order.mapper.order.OaCOrderPersonalMapper;
import com.xnyzc.lhy.order.mapper.order.OaCOrderPersonalOfficialMapper;
import com.xnyzc.lhy.order.mapper.order.OaCSelfStrokeMapper;
import com.xnyzc.lhy.order.mapper.order.OaOrderOtherPriceMapper;
import com.xnyzc.lhy.order.mapper.user.wallet.OaCWalletRecordMapper;
import com.xnyzc.lhy.order.service.order.IOaCCostDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description 费用详情*
 * @Author zhuyubin
 * @Date 2019/8/16 19:31
 **/
@Service
public class OaCCostDetailsServiceImpl implements IOaCCostDetailsService {

    private static final String ZERO = "0.00";

    @Autowired
    private OaCWalletRecordMapper oaCWalletRecordMapper;
    @Autowired
    private OaCOrderPersonalMapper oaCOrderPersonalMapper;
    @Autowired
    private OaCOrderPersonalOfficialMapper oaCOrderPersonalOfficialMapper;
    @Autowired
    private OaCOrderDeptOfficialMapper oaCOrderDeptOfficialMapper;
    @Autowired
    private OaCOrderApprovalOfficialMapper oaCOrderApprovalOfficialMapper;
    @Autowired
    private OaCSelfStrokeMapper oaCSelfStrokeMapper;
    @Autowired
    private OaOrderOtherPriceMapper oaOrderOtherPriceMapper;

    /**
     * 费用详情
     * @param userId 用户id
     * @param tag 租户
     * @param orderNo 订单号
     * @return
     */
    @Override
    public Map<String, Object> getCostDetails(Long userId, String tag, String orderNo){
        Map<String, Object> result = this.initGetCostDetails();
        List<OaOrderOtherPrice> oaOrderOtherPrices = oaOrderOtherPriceMapper.selectList(
                Wrappers.<OaOrderOtherPrice>lambdaQuery()
                        .eq(OaOrderOtherPrice::getTag, tag)
                        .eq(OaOrderOtherPrice::getOrderNo, orderNo)
        );
        // 自费叫车
        if (orderNo.contains(EOrderNoType.ZFJC.getType())){
            return this.getZFJC(userId, tag, orderNo, oaOrderOtherPrices, result);
        }
        // 个人公务
        else if (orderNo.contains(EOrderNoType.GRGW.getType())){
            return this.getGRGW(userId, tag, orderNo, oaOrderOtherPrices, result);
        }
        // 部门公务
        else if (orderNo.contains(EOrderNoType.BMGW.getType())){
            return this.getBMGW(userId, tag, orderNo, oaOrderOtherPrices, result);
        }
        // 审批公务
        else if (orderNo.contains(EOrderNoType.SPGW.getType())){
            return this.getSPGW(userId, tag, orderNo, oaOrderOtherPrices, result);
        }
        // 非法订单号
        else {
            throw PangException.create(EErrorCode.unOrderNo);
        }
    }

    /**
     * 获取代付订单信息
     * @param tag 用户来源
     * @param carpoolSerialNo 邀约拼车流水号
     * @return
     */
    @Override
    public OaCOrderPersonal getInvitationOaCOrderPersonal(String tag, String carpoolSerialNo){
        OaCOrderPersonal oaCOrderPersonal = null;
        // 被邀约人订单
        List<OaCOrderPersonal> oaCOrderPersonals = oaCOrderPersonalMapper.selectList(
                Wrappers.<OaCOrderPersonal>lambdaQuery()
                        .eq(OaCOrder::getTag, tag)
                        .eq(OaCOrder::getInvitationPeopleType, EInvitationPeopleType.beInvitePeople.getValue())
                        .eq(OaCOrder::getInvitationPayType, EInvitationPayType.invitePeoplePay.getValue())
                        .eq(OaCOrder::getInvitationType, EInvitationType.personal.getValue())
                        .eq(OaCOrder::getCarpoolSerialNo, carpoolSerialNo));
        if (oaCOrderPersonals.size() == 1){
            oaCOrderPersonal = oaCOrderPersonals.get(0);
        }
        return oaCOrderPersonal;
    }

    /**
     * 处理小数空
     * @param bigDecimal 数据
     * @return
     */
    @Override
    public BigDecimal bigDecimalIsNull(BigDecimal bigDecimal){
        return CheckUtil.objIsEmpty(bigDecimal) ? new BigDecimal("0") : bigDecimal;
    }

    /**
     * 封装自费叫车
     * @param userId 用户id
     * @param tag 租户
     * @param orderNo 订单号
     * @param result 出参
     * @return
     */
    private Map<String, Object> getZFJC(Long userId, String tag, String orderNo, List<OaOrderOtherPrice> oaOrderOtherPrices, Map<String, Object> result){
        BigDecimal zero = new BigDecimal("0");
        OaCOrderPersonal oaCOrderPersonal = oaCOrderPersonalMapper.selectOne(
                Wrappers.<OaCOrderPersonal>lambdaQuery()
                        .eq(OaCOrder::getUserId, userId)
                        .eq(OaCOrder::getTag, tag)
                        .eq(OaCOrder::getOrderNo, orderNo)
        );
        BigDecimal totalFee = this.bigDecimalIsNull(oaCOrderPersonal.getTotalFee());
        // 判空
        this.beanIsNull(oaCOrderPersonal);
        result.put("coupon", this.nullToStr(oaCOrderPersonal.getCouponDeductionFee()));
        result.put("totalFee", this.nullToStr(oaCOrderPersonal.getTotalFee()));
        result.put("total", this.nullToStr(oaCOrderPersonal.getTotalFee()));
        this.getPayMethod(userId, tag, orderNo, result);
        result.put("selfStrokeList", new ArrayList<>());
        // 代付
        BigDecimal payTransactionFee = null;
        if (EInvitationType.personal.getValue().equals(oaCOrderPersonal.getInvitationType()) && EInvitationPayType.invitePeoplePay.getValue().equals(oaCOrderPersonal.getInvitationPayType())){
            // 邀约拼车流水号
            String carpoolSerialNo = oaCOrderPersonal.getCarpoolSerialNo();
            // 被邀约人订单
            OaCOrderPersonal personal = this.getInvitationOaCOrderPersonal(tag, carpoolSerialNo);
            if (CheckUtil.objIsNotEmpty(personal)){
                payTransactionFee = this.bigDecimalIsNull(personal.getTotalFee());
                if (EInvitationPeopleType.beInvitePeople.getValue().equals(oaCOrderPersonal.getInvitationPeopleType())){
                    result.put("total", zero);
                    result.put("totalFee", zero);
                }
            }
        }
        ResultListUtil resultListUtil = this.initList(
                oaCOrderPersonal.getBaseFee(),
                oaCOrderPersonal.getMilageDistance(),
                false,
                oaCOrderPersonal.getMilageDistance(),
                oaCOrderPersonal.getMileageFee(),
                oaCOrderPersonal.getDurationTime(),
                false,
                oaCOrderPersonal.getDurationTime(),
                oaCOrderPersonal.getDurationFee(),
                oaCOrderPersonal.getDistanceFee(),
                false,
                oaCOrderPersonal.getDistanceFee(),
                oaOrderOtherPrices,
                oaCOrderPersonal.getAwaitFee(),
                oaCOrderPersonal.getServiceFee(),
                oaCOrderPersonal.getEmptyDrivingFee(),
                null,
                null,
                payTransactionFee
        );
        List<Map<String, Object>> list = resultListUtil.getList();
        result.put("list", list);
        return result;
    }

    /**
     * 封装个人公务
     * @param userId 用户id
     * @param tag 租户
     * @param orderNo 订单号
     * @param result 出参
     * @return
     */
    private Map<String, Object> getGRGW(Long userId, String tag, String orderNo, List<OaOrderOtherPrice> oaOrderOtherPrices, Map<String, Object> result){
        OaCOrderPersonalOfficial oaCOrderPersonalOfficial = oaCOrderPersonalOfficialMapper.selectOne(
                Wrappers.<OaCOrderPersonalOfficial>lambdaQuery()
                        .eq(OaCOrder::getUserId, userId)
                        .eq(OaCOrder::getTag, tag)
                        .eq(OaCOrder::getOrderNo, orderNo));
        this.beanIsNull(oaCOrderPersonalOfficial);
        // 私用路段
        List<OaCSelfStroke> oaCSelfStrokes = oaCSelfStrokeMapper.selectList(
                Wrappers.<OaCSelfStroke>lambdaQuery()
                        .eq(OaCSelfStroke::getOrderNo, orderNo)
                        .eq(OaCSelfStroke::getTag, tag));
        DateToStringConverter dateToStringConverter = new DateToStringConverter();
        BigDecimal zero = new BigDecimal("0");
        // 总私用时长费
        BigDecimal selfDurationFee = zero;
        // 总私用里程
        BigDecimal selfMileageDistance = zero;
        // 总私用时长
        BigDecimal selfDurationTime = zero;
        // 总私用里程费
        BigDecimal selfMileageFee = zero;
        List<Map<String, Object>> selfStrokeList = new ArrayList<>();
        for (OaCSelfStroke oaCSelfStroke : oaCSelfStrokes) {
            Map<String, Object> map = new HashMap<>(16);
            // 私用时长费
            BigDecimal durationFee = oaCSelfStroke.getDurationFee();
            if (CheckUtil.objIsNotEmpty(durationFee)){
                selfDurationFee = selfDurationFee.add(durationFee);
            }
            // 私用里程
            BigDecimal mileageDistance = oaCSelfStroke.getMileageDistance();
            if (CheckUtil.objIsNotEmpty(mileageDistance)){
                selfMileageDistance = selfMileageDistance.add(mileageDistance);
            }
            // 私用里程费
            BigDecimal mileageFee = oaCSelfStroke.getMileageFee();
            if (CheckUtil.objIsNotEmpty(mileageFee)){
                selfMileageFee = selfMileageFee.add(mileageFee);
            }
            // 私用时长
            BigDecimal durationTime = oaCSelfStroke.getDurationTime();
            if (CheckUtil.objIsNotEmpty(durationTime)){
                selfDurationTime = selfDurationTime.add(durationTime);
            }
            map.put("time", "");
            map.put("startAddress", "");
            map.put("money", "");
            map.put("endAddress", "");
            Date endTime = oaCSelfStroke.getEndTime();
            Date startTime = oaCSelfStroke.getStartTime();
            map.put("startAddress", CheckUtil.objIsEmpty(oaCSelfStroke.getStartAddress()) ? "" : oaCSelfStroke.getStartAddress());
            map.put("endAddress", CheckUtil.objIsEmpty(oaCSelfStroke.getEndAddress()) ? "" : oaCSelfStroke.getEndAddress());
            map.put("money", String.format("%s%s", this.nullToStr(oaCSelfStroke.getStrokeTotalFee()), EGetCostDetailsName.yuan.getName()));
            if (CheckUtil.objIsNotEmpty(startTime, endTime)){
                map.put("time", String.format("%s~%s", dateToStringConverter.convertFoMinute(startTime), dateToStringConverter.convertFoMinute(endTime)));
            }
            selfStrokeList.add(map);
        }
        // 订单总费用
        BigDecimal totalFee = this.bigDecimalIsNull(oaCOrderPersonalOfficial.getTotalFee());
        result.put("selfStrokeList", selfStrokeList);
        result.put("coupon", this.nullToStr(oaCOrderPersonalOfficial.getCouponDeductionFee()));
        result.put("total", totalFee);
        result.put("totalFee", totalFee);
        // 代付
        BigDecimal payTransactionFee = null;
        if (EInvitationType.personal.getValue().equals(oaCOrderPersonalOfficial.getInvitationType()) && EInvitationPayType.invitePeoplePay.getValue().equals(oaCOrderPersonalOfficial.getInvitationPayType())){
            // 邀约拼车流水号
            String carpoolSerialNo = oaCOrderPersonalOfficial.getCarpoolSerialNo();
            // 被邀约人订单
            OaCOrderPersonal personal = this.getInvitationOaCOrderPersonal(tag, carpoolSerialNo);
            if (CheckUtil.objIsNotEmpty(personal)){
                if (EInvitationPeopleType.invitePeople.getValue().equals(oaCOrderPersonalOfficial.getInvitationPeopleType())){
                    payTransactionFee = this.bigDecimalIsNull(personal.getTotalFee());
                    result.put("total", totalFee.add(payTransactionFee));
                    result.put("totalFee", totalFee.add(payTransactionFee));
                }
            }
        }
        ResultListUtil resultListUtil = this.initList(
                oaCOrderPersonalOfficial.getBaseFee(),
                oaCOrderPersonalOfficial.getMilageDistance(),
                true,
                selfMileageDistance,
                selfMileageFee,
                oaCOrderPersonalOfficial.getDurationTime(),
                true,
                selfDurationTime,
                selfDurationFee,
                oaCOrderPersonalOfficial.getDistanceFee(),
                false,
                oaCOrderPersonalOfficial.getDistanceFee(),
                oaOrderOtherPrices,
                oaCOrderPersonalOfficial.getAwaitFee(),
                oaCOrderPersonalOfficial.getServiceFee(),
                oaCOrderPersonalOfficial.getEmptyDrivingFee(),
                oaCOrderPersonalOfficial.getMileageFee(),
                oaCOrderPersonalOfficial.getDurationFee(),
                payTransactionFee

        );
        result.put("list", resultListUtil.getList());
        return this.getPayMethod(userId, tag, orderNo, result);
    }

    /**
     * 封装部门公务
     * @param userId 用户id
     * @param tag 租户
     * @param orderNo 订单号
     * @param result 出参
     * @return
     */
    private Map<String, Object> getBMGW(Long userId, String tag, String orderNo, List<OaOrderOtherPrice> oaOrderOtherPrices, Map<String, Object> result){
        OaCOrderDeptOfficial oaCOrderDeptOfficial = oaCOrderDeptOfficialMapper.selectOne(
                Wrappers.<OaCOrderDeptOfficial>lambdaQuery()
                        .eq(OaCOrder::getUserId, userId)
                        .eq(OaCOrder::getTag, tag)
                        .eq(OaCOrder::getOrderNo, orderNo)
        );
        this.beanIsNull(oaCOrderDeptOfficial);
        ResultListUtil resultListUtil = this.initList(
                oaCOrderDeptOfficial.getBaseFee(),
                oaCOrderDeptOfficial.getMilageDistance(),
                true,
                null,
                null,
                oaCOrderDeptOfficial.getDurationTime(),
                true,
                null,
                null,
                oaCOrderDeptOfficial.getDistanceFee(),
                true,
                null,
                oaOrderOtherPrices,
                oaCOrderDeptOfficial.getAwaitFee(),
                oaCOrderDeptOfficial.getServiceFee(),
                oaCOrderDeptOfficial.getEmptyDrivingFee(),
                oaCOrderDeptOfficial.getMileageFee(),
                oaCOrderDeptOfficial.getDurationFee(),
                null
        );
        List<Map<String, Object>> list = resultListUtil.getList();
        result.put("list", list);
        result.put("total", this.nullToStr(oaCOrderDeptOfficial.getTotalFee()));
        result.put("totalFee", this.nullToStr(oaCOrderDeptOfficial.getTotalFee()));
        result.put("coupon", this.nullToStr(oaCOrderDeptOfficial.getCouponDeductionFee()));
        this.getPayMethod(userId, tag, orderNo, result);
        result.put("selfStrokeList", new ArrayList<>());
        return result;
    }

    /**
     * 封装审批公务
     * @param userId 用户id
     * @param tag 租户
     * @param orderNo 订单号
     * @param result 出参
     * @return
     */
    private Map<String, Object> getSPGW(Long userId, String tag, String orderNo, List<OaOrderOtherPrice> oaOrderOtherPrices, Map<String, Object> result){
        OaCOrderApprovalOfficial oaCOrderApprovalOfficial = oaCOrderApprovalOfficialMapper.selectOne(
                Wrappers.<OaCOrderApprovalOfficial>lambdaQuery()
                        .eq(OaCOrderApprovalOfficial::getUserId, userId)
                        .eq(OaCOrderApprovalOfficial::getTag, tag)
                        .eq(OaCOrderApprovalOfficial::getOrderNo, orderNo));
        this.beanIsNull(oaCOrderApprovalOfficial);
        // 私用路段
        List<OaCSelfStroke> oaCSelfStrokes = oaCSelfStrokeMapper.selectList(
                Wrappers.<OaCSelfStroke>lambdaQuery()
                        .eq(OaCSelfStroke::getOrderNo, orderNo)
                        .eq(OaCSelfStroke::getTag, tag));
        BigDecimal zero = new BigDecimal("0");
        DateToStringConverter dateToStringConverter = new DateToStringConverter();
        // 总私用时长
        BigDecimal selfDurationTime = zero;
        // 总私用时长费
        BigDecimal selfDurationFee = zero;
        // 总私用里程费
        BigDecimal selfMileageFee = zero;
        // 总私用里程
        BigDecimal selfMileageDistance = zero;
        List<Map<String, Object>> selfStrokeList = new ArrayList<>();
        for (OaCSelfStroke oaCSelfStroke : oaCSelfStrokes) {
            Map<String, Object> map = new HashMap<>(16);
            // 私用时长费
            BigDecimal durationFee = oaCSelfStroke.getDurationFee();
            if (CheckUtil.objIsNotEmpty(durationFee)){
                selfDurationFee = selfDurationFee.add(durationFee);
            }
            // 私用时长
            BigDecimal durationTime = oaCSelfStroke.getDurationTime();
            if (CheckUtil.objIsNotEmpty(durationTime)){
                selfDurationTime = selfDurationTime.add(durationTime);
            }
            // 私用里程费
            BigDecimal mileageFee = oaCSelfStroke.getMileageFee();
            if (CheckUtil.objIsNotEmpty(mileageFee)){
                selfMileageFee = selfMileageFee.add(mileageFee);
            }
            // 私用里程
            BigDecimal mileageDistance = oaCSelfStroke.getMileageDistance();
            if (CheckUtil.objIsNotEmpty(mileageDistance)){
                selfMileageDistance = selfMileageDistance.add(mileageDistance);
            }
            map.put("time", "");
            map.put("startAddress", "");
            map.put("endAddress", "");
            map.put("money", "");
            Date startTime = oaCSelfStroke.getStartTime();
            Date endTime = oaCSelfStroke.getEndTime();
            if (CheckUtil.objIsNotEmpty(startTime, endTime)){
                map.put("time", String.format("%s~%s", dateToStringConverter.convertFoMinute(startTime), dateToStringConverter.convertFoMinute(endTime)));
            }
            map.put("startAddress", CheckUtil.objIsEmpty(oaCSelfStroke.getStartAddress()) ? "" : oaCSelfStroke.getStartAddress());
            map.put("endAddress", CheckUtil.objIsEmpty(oaCSelfStroke.getEndAddress()) ? "" : oaCSelfStroke.getEndAddress());
            map.put("money", String.format("%s%s", this.nullToStr(oaCSelfStroke.getStrokeTotalFee()), EGetCostDetailsName.yuan.getName()));
            selfStrokeList.add(map);
        }
        // 订单总费用
        BigDecimal totalFee = this.bigDecimalIsNull(oaCOrderApprovalOfficial.getTotalFee());
        result.put("selfStrokeList", selfStrokeList);
        result.put("coupon", this.nullToStr(oaCOrderApprovalOfficial.getCouponDeductionFee()));
        result.put("totalFee", totalFee);
        result.put("total", totalFee);
        // 代付
        BigDecimal payTransactionFee = null;
        if (EInvitationType.personal.getValue().equals(oaCOrderApprovalOfficial.getInvitationType()) && EInvitationPayType.invitePeoplePay.getValue().equals(oaCOrderApprovalOfficial.getInvitationPayType())){
            // 邀约拼车流水号
            String carpoolSerialNo = oaCOrderApprovalOfficial.getCarpoolSerialNo();
            // 被邀约人订单
            OaCOrderPersonal personal = this.getInvitationOaCOrderPersonal(tag, carpoolSerialNo);
            if (CheckUtil.objIsNotEmpty(personal)){
                if (EInvitationPeopleType.invitePeople.getValue().equals(oaCOrderApprovalOfficial.getInvitationPeopleType())){
                    payTransactionFee = this.bigDecimalIsNull(personal.getTotalFee());
                    result.put("totalFee", totalFee.add(payTransactionFee));
                    result.put("total", totalFee.add(payTransactionFee));
                }
            }
        }
        ResultListUtil resultListUtil = this.initList(
                oaCOrderApprovalOfficial.getBaseFee(),
                oaCOrderApprovalOfficial.getMilageDistance(),
                true,
                selfMileageDistance,
                selfMileageFee,
                oaCOrderApprovalOfficial.getDurationTime(),
                true,
                selfDurationTime,
                selfDurationFee,
                oaCOrderApprovalOfficial.getDistanceFee(),
                false,
                oaCOrderApprovalOfficial.getDistanceFee(),
                oaOrderOtherPrices,
                oaCOrderApprovalOfficial.getAwaitFee(),
                oaCOrderApprovalOfficial.getServiceFee(),
                oaCOrderApprovalOfficial.getEmptyDrivingFee(),
                oaCOrderApprovalOfficial.getMileageFee(),
                oaCOrderApprovalOfficial.getDurationFee(),
                payTransactionFee
        );
        List<Map<String, Object>> list = resultListUtil.getList();
        result.put("list", list);
        return this.getPayMethod(userId, tag, orderNo, result);
    }

    /**
     * 获取支付方式
     * @param userId 用户id
     * @param tag 租户
     * @param orderNo 订单号
     * @param result 出参
     * @return
     */
    private Map<String, Object> getPayMethod(Long userId, String tag, String orderNo, Map<String, Object> result){
        List<OaCWalletRecord> oaCWalletRecords = oaCWalletRecordMapper.selectList(
                Wrappers.<OaCWalletRecord>lambdaQuery()
                        .eq(OaCWalletRecord::getUserId, userId)
                        .eq(OaCWalletRecord::getTag, tag)
                        .eq(OaCWalletRecord::getIsTransaction, EIsTransaction.paySuccess.getValue())
                        .eq(OaCWalletRecord::getOrderNo, orderNo)
        );
        ResultListUtil resultListUtil = new ResultListUtil();
        for (OaCWalletRecord oaCWalletRecord : oaCWalletRecords) {
            resultListUtil.add(
                    ERecordType.findById(oaCWalletRecord.getRecordType()).getValue(),
                    String.format("%s%s", this.nullToStr(oaCWalletRecord.getActualAmount()), EGetCostDetailsName.yuan.getName())
            );
        }
        List<Map<String, Object>> payModeList = resultListUtil.getList();
        result.put("payModeList", payModeList);
        return result;
    }

    /**
     * 费用详情基础列表
     * @param baseFee 基础费
     * @param milageDistance 里程
     * @param isPubMilage 是否有公用里程
     * @param priMileageDistance 私用里程
     * @param priMileageFee 私用里程费
     * @param durationTime 时长
     * @param isPubDuration 是否有公用时长费
     * @param priDurationTime 私用时长
     * @param priDurationFee 私用时长费
     * @param longDistanceFee 远途费
     * @param isPubLongDistanceFee 是否有公用远途费
     * @param priLongDistanceFee 私用远途费
     * @param pubMileageFee 公用里程费
     * @param pubDurationFee 公用时长费
     * @return
     */
    private ResultListUtil initList(
            BigDecimal baseFee,
            BigDecimal milageDistance,
            boolean isPubMilage,
            BigDecimal priMileageDistance,
            BigDecimal priMileageFee,
            BigDecimal durationTime,
            boolean isPubDuration,
            BigDecimal priDurationTime,
            BigDecimal priDurationFee,
            BigDecimal longDistanceFee,
            boolean isPubLongDistanceFee,
            BigDecimal priLongDistanceFee,
            List<OaOrderOtherPrice> oaOrderOtherPrices,
            BigDecimal awaitFee,
            BigDecimal serviceFee,
            BigDecimal emptyDrivingFee,
            BigDecimal pubMileageFee,
            BigDecimal pubDurationFee,
            BigDecimal payTransactionFee
    ){
        BigDecimal zero = new BigDecimal("0");
        ResultListUtil resultListUtil = new ResultListUtil();
        // 如果 时长总费 加 里程总费 小于 基础费全部显示 0 并展示基础费
        if (this.bigDecimalIsNull(pubMileageFee)
                .add(this.bigDecimalIsNull(priMileageFee))
                .add(this.bigDecimalIsNull(pubDurationFee))
                .add(this.bigDecimalIsNull(priDurationFee)).compareTo(this.bigDecimalIsNull(baseFee)) == -1) {
            pubMileageFee = zero;
            priMileageFee = zero;
            pubDurationFee = zero;
            priDurationFee = zero;
            // 基础费
            resultListUtil.add(EGetCostDetailsName.baseFee.getName(), String.format("%s%s", this.nullToStr(baseFee), EGetCostDetailsName.yuan.getName()), 0);
        }
        // 总里程
        //milageDistance = this.bigDecimalIsNull(milageDistance);
        resultListUtil
                .add(EGetCostDetailsName.totalMileageFee.getName(),
                        String.format("%s%s", this.bigDecimalIsNull(pubMileageFee).add(this.bigDecimalIsNull(priMileageFee)), EGetCostDetailsName.yuan.getName()), 0);
        /*// 公用里程
        if (isPubMilage){
            if (this.isNotNull(milageDistance)){
                resultListUtil.add(
                        String.format(EGetCostDetailsName.publicMileage.getName(), milageDistance.subtract(this.bigDecimalIsNull(priMileageDistance))),
                        String.format("%s%s", this.bigDecimalIsNull(pubMileageFee), EGetCostDetailsName.yuan.getName()), 1);
            }
        }
        // 私用里程
        if (this.isNotNull(priMileageFee)){
            resultListUtil.add(
                    String.format(EGetCostDetailsName.privateMileage.getName(), priMileageDistance),
                    String.format("%s%s", priMileageFee, EGetCostDetailsName.yuan.getName()),1);
        }*/
        // 总时长
        //durationTime = this.bigDecimalIsNull(durationTime);
        resultListUtil.add(EGetCostDetailsName.totalTimeFee.getName(),
                String.format("%s%s", this.bigDecimalIsNull(pubDurationFee).add(this.bigDecimalIsNull(priDurationFee)), EGetCostDetailsName.yuan.getName()), 0);
        /*// 公用时长费
        if (isPubDuration){
            if (this.isNotNull(durationTime)){
                resultListUtil.add(
                        String.format(EGetCostDetailsName.pub.getName(), durationTime.subtract(this.bigDecimalIsNull(priDurationTime))),
                        String.format("%s%s", this.bigDecimalIsNull(pubDurationFee), EGetCostDetailsName.yuan.getName()), 1);
            }
        }
        // 私用时长费
        if (this.isNotNull(priDurationFee)){
            resultListUtil
                    .add(
                            String.format(pri.getName(), priDurationTime),
                            String.format("%s%s", priDurationFee, EGetCostDetailsName.yuan.getName()), 1);
        }*/
        // 远途费
        if (this.isNotNull(longDistanceFee)){
            resultListUtil.add(EGetCostDetailsName.longDistanceFee.getName(), String.format("%s%s", longDistanceFee, EGetCostDetailsName.yuan.getName()), 0);
            if (isPubLongDistanceFee){
                resultListUtil.add(EGetCostDetailsName.pub.getName(), String.format("%s%s", longDistanceFee, EGetCostDetailsName.yuan.getName()), 1);
            }
            if (this.isNotNull(priLongDistanceFee)){
                resultListUtil.add(EGetCostDetailsName.pri.getName(), String.format("%s%s", priLongDistanceFee, EGetCostDetailsName.yuan.getName()), 1);
            }
        }
        // 其他费用
        if (CheckUtil.objIsNotEmpty(oaOrderOtherPrices)){
            BigDecimal otherMoney = new BigDecimal("0");
            for (OaOrderOtherPrice oaOrderOtherPrice : oaOrderOtherPrices) {
                otherMoney = otherMoney.add(oaOrderOtherPrice.getCostAmount());
            }
            otherMoney = otherMoney.add(this.bigDecimalIsNull(awaitFee)).add(this.bigDecimalIsNull(serviceFee)).add(this.bigDecimalIsNull(emptyDrivingFee));
            if (this.isNotNull(otherMoney)){
                resultListUtil.add(EGetCostDetailsName.otherMoney.getName(), String.format("%s%s", otherMoney, EGetCostDetailsName.yuan.getName()), 0);
            }
            for (OaOrderOtherPrice oaOrderOtherPrice : oaOrderOtherPrices) {
                if (this.isNotNull(oaOrderOtherPrice.getCostAmount())){
                    resultListUtil.add(EOrderOtherPrice.findById(oaOrderOtherPrice.getCostType()).getValue(), String.format("%s%s", oaOrderOtherPrice.getCostAmount(), EGetCostDetailsName.yuan.getName()), 1);
                }
            }
            /*if (this.isNotNull(awaitFee)){
                resultListUtil.add(EGetCostDetailsName.awaitFee.getName(), String.format("%s%s", awaitFee, EGetCostDetailsName.yuan.getName()), 1);
            }
            if (this.isNotNull(serviceFee)){
                resultListUtil.add(EGetCostDetailsName.serviceFee.getName(), String.format("%s%s", serviceFee, EGetCostDetailsName.yuan.getName()), 1);
            }
            if (this.isNotNull(emptyDrivingFee)){
                resultListUtil.add(EGetCostDetailsName.emptyDrivingFee.getName(), String.format("%s%s", emptyDrivingFee, EGetCostDetailsName.yuan.getName()), 1);
            }*/
        }
        // 代付费用
        if (this.isNotNull(payTransactionFee)){
            resultListUtil.add(EGetCostDetailsName.payTransactionFee.getName(), String.format("%s%s", payTransactionFee, EGetCostDetailsName.yuan.getName()), 0);
        }
        return resultListUtil;
    }

    /**
     * 处理int 的 null
     * @param integer 数据
     * @return
     */
    private Integer integerIsNull(Integer integer){
        return CheckUtil.objIsEmpty(integer) ? 0 : integer;
    }

    /**
     * 判断实体是否为null
     * @param value 实体
     */
    private void beanIsNull(Object value){
        if (CheckUtil.objIsEmpty(value)){
            throw PangException.create(EErrorCode.unOrder);
        }
    }

    /**
     * 判断是否是空或0
     * @param value
     * @return
     */
    private boolean isNotNull(Object value){
        return !(CheckUtil.objIsEmpty(value) || value.toString().equals(ZERO) || new BigDecimal("0").compareTo(new BigDecimal(value.toString())) == 0);
    }

    /**
     * 判空顺便转字符串
     * @param value 数据
     * @return
     */
    private String nullToStr(Object value){
        return CheckUtil.objIsEmpty(value) ? "0" : value.toString();
    }

    /**
     * 初始化出参
     * @return
     */
    private Map<String, Object> initGetCostDetails(){
        Map<String, Object> result = new HashMap<>(16);
        result.put("list", new ArrayList<>());
        result.put("total", "");
        result.put("coupon", "");
        result.put("totalFee", "");
        result.put("payModeList", new ArrayList<>());
        result.put("selfStrokeList", new ArrayList<>());
        return result;
    }
}
